import React, { useState, useMemo, useCallback, useRef, useEffect } from 'react'
import { FixedSizeList as List, ListChildComponentProps } from 'react-window'
import InfiniteLoader from 'react-window-infinite-loader'
import { format } from 'date-fns'
import { zhCN } from 'date-fns/locale'
import { Eye, Copy, ChevronRight, ChevronDown, Search, Filter } from 'lucide-react'
import { KafkaMessage } from '@/stores/kafkaStore'
import toast from 'react-hot-toast'

interface VirtualizedMessageTableProps {
  messages: KafkaMessage[]
  loading?: boolean
  hasNextPage?: boolean
  isNextPageLoading?: boolean
  loadNextPage?: () => Promise<void>
  totalCount?: number
  onSearch?: (query: string) => void
  onFilter?: (filters: MessageFilters) => void
}

interface MessageFilters {
  partition?: number
  timeRange?: {
    start: Date
    end: Date
  }
  keyPattern?: string
  valuePattern?: string
  minOffset?: number
  maxOffset?: number
}

interface ExpandedRows {
  [key: string]: boolean
}

// 行高配置
const ROW_HEIGHT = 60 // 基础行高
const EXPANDED_ROW_HEIGHT = 300 // 展开行高
const HEADER_HEIGHT = 50 // 表头高度

// 虚拟化行组件
const MessageRow = React.memo(({ index, style, data }: ListChildComponentProps) => {
  const { 
    messages, 
    expandedRows, 
    toggleRow, 
    copyToClipboard, 
    formatValue, 
    formatTimestamp, 
    getMessageId 
  } = data

  // 处理加载状态
  if (index >= messages.length) {
    return (
      <div style={style} className="flex items-center justify-center">
        <div className="animate-spin rounded-full h-6 w-6 border-b-2 border-primary-600"></div>
        <span className="ml-2 text-gray-600">加载更多...</span>
      </div>
    )
  }

  const message = messages[index]
  const messageId = getMessageId(message, index)
  const isExpanded = expandedRows[messageId]
  
  const valuePreview = typeof message.value === 'object' 
    ? JSON.stringify(message.value).slice(0, 80) + '...'
    : String(message.value).slice(0, 80) + (String(message.value).length > 80 ? '...' : '')

  return (
    <div style={style} className="border-b border-gray-200">
      {/* 主行 */}
      <div className="flex items-center h-[60px] px-4 hover:bg-gray-50">
        {/* 展开按钮 */}
        <div className="w-8 flex-shrink-0">
          <button
            onClick={() => toggleRow(messageId)}
            className="p-1 hover:bg-gray-100 rounded"
          >
            {isExpanded ? (
              <ChevronDown className="h-4 w-4" />
            ) : (
              <ChevronRight className="h-4 w-4" />
            )}
          </button>
        </div>

        {/* 时间戳 */}
        <div className="w-40 flex-shrink-0 text-sm text-gray-600">
          {formatTimestamp(message.timestamp)}
        </div>

        {/* 分区 */}
        <div className="w-16 flex-shrink-0">
          <span className="inline-flex items-center px-2 py-1 rounded-full text-xs font-medium bg-blue-100 text-blue-800">
            {message.partition}
          </span>
        </div>

        {/* 偏移量 */}
        <div className="w-24 flex-shrink-0 font-mono text-sm">
          {message.offset}
        </div>

        {/* Key */}
        <div className="w-32 flex-shrink-0">
          {message.key ? (
            <span className="font-mono text-xs bg-gray-100 px-2 py-1 rounded truncate block">
              {message.key}
            </span>
          ) : (
            <span className="text-gray-400">-</span>
          )}
        </div>

        {/* Value预览 */}
        <div className="flex-1 min-w-0 mr-4">
          <div className="font-mono text-sm text-gray-700 truncate">
            {valuePreview}
          </div>
        </div>

        {/* 操作按钮 */}
        <div className="w-10 flex-shrink-0">
          <button
            onClick={() => copyToClipboard(formatValue(message.value))}
            className="p-1 hover:bg-gray-100 rounded"
            title="复制Value"
          >
            <Copy className="h-4 w-4" />
          </button>
        </div>
      </div>

      {/* 展开内容 */}
      {isExpanded && (
        <div className="px-4 pb-4 bg-gray-50 border-t">
          <div className="space-y-4 py-4">
            {/* Key详情 */}
            {message.key && (
              <div>
                <h4 className="text-sm font-medium text-gray-700 mb-2">Key:</h4>
                <pre className="bg-white p-3 rounded border text-sm font-mono overflow-x-auto max-h-20 overflow-y-auto">
                  {message.key}
                </pre>
              </div>
            )}
            
            {/* Value详情 */}
            <div>
              <h4 className="text-sm font-medium text-gray-700 mb-2">Value:</h4>
              <pre className="bg-white p-3 rounded border text-sm font-mono overflow-x-auto max-h-40 overflow-y-auto">
                {formatValue(message.value)}
              </pre>
            </div>
            
            {/* Headers */}
            {Object.keys(message.headers).length > 0 && (
              <div>
                <h4 className="text-sm font-medium text-gray-700 mb-2">Headers:</h4>
                <pre className="bg-white p-3 rounded border text-sm font-mono overflow-x-auto max-h-20 overflow-y-auto">
                  {JSON.stringify(message.headers, null, 2)}
                </pre>
              </div>
            )}
            
            {/* 元数据 */}
            <div>
              <h4 className="text-sm font-medium text-gray-700 mb-2">元数据:</h4>
              <div className="bg-white p-3 rounded border text-sm">
                <div className="grid grid-cols-2 md:grid-cols-4 gap-4">
                  <div>
                    <span className="text-gray-500">Topic:</span>
                    <div className="font-mono">{message.topic}</div>
                  </div>
                  <div>
                    <span className="text-gray-500">分区:</span>
                    <div className="font-mono">{message.partition}</div>
                  </div>
                  <div>
                    <span className="text-gray-500">偏移量:</span>
                    <div className="font-mono">{message.offset}</div>
                  </div>
                  <div>
                    <span className="text-gray-500">时间戳:</span>
                    <div className="font-mono">{message.timestamp || '-'}</div>
                  </div>
                </div>
              </div>
            </div>
          </div>
        </div>
      )}
    </div>
  )
})

MessageRow.displayName = 'MessageRow'

export default function VirtualizedMessageTable({
  messages,
  loading = false,
  hasNextPage = false,
  isNextPageLoading = false,
  loadNextPage,
  totalCount,
  onSearch,
  onFilter
}: VirtualizedMessageTableProps) {
  const [expandedRows, setExpandedRows] = useState<ExpandedRows>({})
  const [searchQuery, setSearchQuery] = useState('')
  const [showFilters, setShowFilters] = useState(false)
  const listRef = useRef<List>(null)

  const toggleRow = useCallback((messageId: string) => {
    setExpandedRows(prev => ({
      ...prev,
      [messageId]: !prev[messageId]
    }))
  }, [])

  const copyToClipboard = useCallback((text: string) => {
    navigator.clipboard.writeText(text).then(() => {
      toast.success('已复制到剪贴板')
    }).catch(() => {
      toast.error('复制失败')
    })
  }, [])

  const formatValue = useCallback((value: any) => {
    if (typeof value === 'object') {
      return JSON.stringify(value, null, 2)
    }
    return String(value)
  }, [])

  const formatTimestamp = useCallback((timestamp?: number) => {
    if (!timestamp) return '-'
    return format(new Date(timestamp), 'MM-dd HH:mm:ss', { locale: zhCN })
  }, [])

  const getMessageId = useCallback((message: KafkaMessage, index: number) => {
    return `${message.topic}-${message.partition}-${message.offset}-${index}`
  }, [])

  // 计算动态行高
  const getItemSize = useCallback((index: number) => {
    if (index >= messages.length) return ROW_HEIGHT
    
    const message = messages[index]
    const messageId = getMessageId(message, index)
    const isExpanded = expandedRows[messageId]
    
    return isExpanded ? EXPANDED_ROW_HEIGHT : ROW_HEIGHT
  }, [messages, expandedRows, getMessageId])

  // 无限加载配置
  const itemCount = hasNextPage ? messages.length + 1 : messages.length
  const isItemLoaded = useCallback((index: number) => !!messages[index], [messages])

  // 传递给虚拟化行的数据
  const itemData = useMemo(() => ({
    messages,
    expandedRows,
    toggleRow,
    copyToClipboard,
    formatValue,
    formatTimestamp,
    getMessageId
  }), [messages, expandedRows, toggleRow, copyToClipboard, formatValue, formatTimestamp, getMessageId])

  // 处理搜索
  const handleSearch = useCallback((e: React.FormEvent) => {
    e.preventDefault()
    if (onSearch) {
      onSearch(searchQuery)
    }
  }, [searchQuery, onSearch])

  if (loading && messages.length === 0) {
    return (
      <div className="card">
        <div className="card-content">
          <div className="flex items-center justify-center py-12">
            <div className="animate-spin rounded-full h-8 w-8 border-b-2 border-primary-600"></div>
            <span className="ml-2 text-gray-600">加载中...</span>
          </div>
        </div>
      </div>
    )
  }

  if (messages.length === 0) {
    return (
      <div className="card">
        <div className="card-content">
          <div className="text-center py-12">
            <Eye className="h-12 w-12 text-gray-400 mx-auto mb-4" />
            <h3 className="text-lg font-medium text-gray-900 mb-2">暂无消息</h3>
            <p className="text-gray-600">选择一个Topic并加载消息或开始实时流式</p>
          </div>
        </div>
      </div>
    )
  }

  return (
    <div className="card">
      {/* 表头和搜索 */}
      <div className="card-header">
        <div className="flex items-center justify-between">
          <div>
            <h3 className="card-title">消息列表</h3>
            <p className="card-description">
              共 {totalCount || messages.length} 条消息
              {totalCount && totalCount > messages.length && ` (已加载 ${messages.length} 条)`}
            </p>
          </div>
          
          {/* 搜索和过滤 */}
          <div className="flex items-center space-x-2">
            <form onSubmit={handleSearch} className="flex items-center">
              <div className="relative">
                <Search className="absolute left-3 top-1/2 transform -translate-y-1/2 h-4 w-4 text-gray-400" />
                <input
                  type="text"
                  placeholder="搜索消息内容..."
                  value={searchQuery}
                  onChange={(e) => setSearchQuery(e.target.value)}
                  className="pl-10 pr-4 py-2 border border-gray-300 rounded-md focus:ring-2 focus:ring-primary-500 focus:border-transparent"
                />
              </div>
              <button
                type="submit"
                className="ml-2 px-4 py-2 bg-primary-600 text-white rounded-md hover:bg-primary-700"
              >
                搜索
              </button>
            </form>
            
            <button
              onClick={() => setShowFilters(!showFilters)}
              className="p-2 border border-gray-300 rounded-md hover:bg-gray-50"
              title="过滤器"
            >
              <Filter className="h-4 w-4" />
            </button>
          </div>
        </div>
      </div>

      {/* 表格头部 */}
      <div className="border-b border-gray-200 bg-gray-50">
        <div className="flex items-center h-[50px] px-4 text-sm font-medium text-gray-700">
          <div className="w-8 flex-shrink-0"></div>
          <div className="w-40 flex-shrink-0">时间戳</div>
          <div className="w-16 flex-shrink-0">分区</div>
          <div className="w-24 flex-shrink-0">偏移量</div>
          <div className="w-32 flex-shrink-0">Key</div>
          <div className="flex-1 min-w-0 mr-4">Value预览</div>
          <div className="w-10 flex-shrink-0">操作</div>
        </div>
      </div>

      {/* 虚拟化列表 */}
      <div className="card-content p-0">
        <InfiniteLoader
          isItemLoaded={isItemLoaded}
          itemCount={itemCount}
          loadMoreItems={loadNextPage || (() => Promise.resolve())}
        >
          {({ onItemsRendered, ref }) => (
            <List
              ref={(list) => {
                listRef.current = list
                ref(list)
              }}
              height={600} // 固定高度，可以根据需要调整
              itemCount={itemCount}
              itemSize={getItemSize}
              itemData={itemData}
              onItemsRendered={onItemsRendered}
              overscanCount={5} // 预渲染5行以提升滚动性能
            >
              {MessageRow}
            </List>
          )}
        </InfiniteLoader>
      </div>
    </div>
  )
}
